package com.baijiayun.liveuibase.devicetesting.fragment

import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.RotateAnimation
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.baijiahulian.common.cropperv2.utils.DeviceUtils
import com.baijiayun.livecore.utils.LPReportUtil
import com.baijiayun.livecore.utils.LPRxUtils
import com.baijiayun.liveuibase.R
import com.baijiayun.liveuibase.devicetesting.DeviceTestingViewModel
import com.baijiayun.liveuibase.utils.NetworkUtils
import com.baijiayun.liveuibase.utils.PConst
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.bjy_base_fragment_device_testing_net.*
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.nio.ByteBuffer
import java.text.DecimalFormat
import java.util.concurrent.TimeUnit
import java.util.jar.Manifest

class DeviceTestingNetFragment : Fragment() {
    private lateinit var viewModel : DeviceTestingViewModel
    private val uploadFilePath by lazy {
        (context?.cacheDir?.absolutePath ?: "") + "/upload_net_test.txt"
    }
    private val downloadFilePath by lazy {
        (context?.cacheDir?.absolutePath ?: "") + "/download_net_test.txt"
    }
    private val rotateAnimator by lazy {
        RotateAnimation(0f, 360f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f)
    }

    private val netStateObserver by lazy {
        Observer<DeviceTestingViewModel.NetState> {
            when(it) {
                DeviceTestingViewModel.NetState.None -> startLoading()
                DeviceTestingViewModel.NetState.Mobile, DeviceTestingViewModel.NetState.Wifi -> checkNet()
            }
        }
    }

    private val netUploadSpeedObserver by lazy {
        Observer<Float> {
            bjy_base_fragment_device_testing_upload_loading.apply {
                this.clearAnimation()
                this.visibility = View.GONE
            }
            bjy_base_fragment_device_testing_upload_tv.apply {
                this.text = "$it Mbps"
                this.visibility = View.VISIBLE
            }
            if (bjy_base_fragment_device_testing_download_loading.visibility == View.GONE) {
                testFinish()
            }
        }
    }

    private val netDownloadSpeedObserver by lazy {
        Observer<Float> {
            bjy_base_fragment_device_testing_download_loading.apply {
                this.clearAnimation()
                this.visibility = View.GONE
            }
            bjy_base_fragment_device_testing_download_tv.apply {
                this.text = "$it Mbps"
                this.visibility = View.VISIBLE
            }
            if (bjy_base_fragment_device_testing_upload_loading.visibility == View.GONE) {
                testFinish()
            }
        }
    }

    private val netIpObserver by lazy {
        Observer<String> {
            bjy_base_fragment_device_testing_net_ip_tv.apply {
                this.visibility = View.VISIBLE
                this.text = it
            }
            bjy_base_fragment_device_testing_net_ip_loading.apply {
                this.clearAnimation()
                this.visibility = View.GONE
            }
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.bjy_base_fragment_device_testing_net, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewModel = ViewModelProvider(requireActivity()).get(DeviceTestingViewModel::class.java)
        initAction()
        initView()
    }

    private fun initView() {
        bjy_base_fragment_device_testing_net_next_step_btn.visibility = View.GONE
        bjy_base_fragment_device_testing_net_description_tv.visibility = View.GONE
        bjy_base_fragment_device_testing_operating_system_tv.text = "Android ${Build.VERSION.RELEASE}"
        bjy_base_fragment_device_testing_client_tv.text = "V ${LPReportUtil.getVersionName(context)}"
        bjy_base_fragment_device_testing_net_next_step_btn.setOnClickListener {
            viewModel.netResult = true
            viewModel.setTestStep(DeviceTestingViewModel.TestStep.TestCamera)
        }
        startLoading()
        if (!NetworkUtils.isNetConnected(context)) {
            bjy_base_fragment_device_testing_net_description_tv.apply {
                this.text = getText(R.string.bjy_base_device_testing_net_reconnect)
                this.setTextColor(ContextCompat.getColor(context!!, R.color.bjy_base_window_loading_device_check_failed_text_color))
                this.visibility = View.VISIBLE
            }
            bjy_base_fragment_device_testing_net_next_step_btn.apply {
                this.visibility = View.VISIBLE
                this.isEnabled = false
                this.setTextColor(ContextCompat.getColor(context!!, R.color.bjy_base_window_loading_tip_text_color))
            }
            return
        }
        checkNet()
    }

    private fun initAction() {
        viewModel.netState.observeForever(netStateObserver)
        viewModel.uploadSpeed.observeForever(netUploadSpeedObserver)
        viewModel.downloadSpeed.observeForever(netDownloadSpeedObserver)
        viewModel.netIp.observeForever(netIpObserver)
    }

    private fun startLoading() {
        rotateAnimator.duration = 500
        rotateAnimator.repeatCount = -1
        rotateAnimator.fillAfter = true
        bjy_base_fragment_device_testing_net_ip_tv.visibility = View.GONE
        bjy_base_fragment_device_testing_net_type_tv.visibility = View.GONE
        bjy_base_fragment_device_testing_upload_tv.visibility = View.GONE
        bjy_base_fragment_device_testing_download_tv.visibility = View.GONE
        bjy_base_fragment_device_testing_net_ip_loading.apply {
            this.visibility = View.VISIBLE
            this.startAnimation(rotateAnimator)
        }
        bjy_base_fragment_device_testing_net_type_loading.apply {
            this.visibility = View.VISIBLE
            this.startAnimation(rotateAnimator)
        }
        bjy_base_fragment_device_testing_upload_loading.apply {
            this.visibility = View.VISIBLE
            this.startAnimation(rotateAnimator)
        }
        bjy_base_fragment_device_testing_download_loading.apply {
            this.visibility = View.VISIBLE
            this.startAnimation(rotateAnimator)
        }
    }

    @SuppressLint("NewApi")
    private fun checkNet() {
        bjy_base_fragment_device_testing_net_description_tv.visibility = View.INVISIBLE
        bjy_base_fragment_device_testing_net_next_step_btn.visibility = View.INVISIBLE
        bjy_base_fragment_device_testing_net_type_loading.apply {
            this.clearAnimation()
            this.visibility = View.GONE
        }
        bjy_base_fragment_device_testing_net_type_tv.apply {
            this.visibility = View.VISIBLE
            this.text = when (NetworkUtils.getNetworkState(context)) {
                PConst.NETWORK_STATE_WIFI -> "WIFI"
                PConst.NETWORK_STATE_3G -> "3G"
                PConst.NETWORK_STATE_4G -> "4G"
                PConst.NETWORK_STATE_5G -> "5G"
                else -> getText(R.string.bjy_base_device_testing_net_unknown)
            }
            viewModel.netType = this.text as String
        }
        createMbFile(10)
        viewModel.downloadTest(downloadFilePath)
    }

    private fun testFinish() {
        bjy_base_fragment_device_testing_net_description_tv.apply {
            this.text = getText(R.string.bjy_base_device_testing_net_check_done)
            this.setTextColor(ContextCompat.getColor(context!!, R.color.bjy_base_device_testing_main_text_color))
            this.visibility = View.VISIBLE
        }
        bjy_base_fragment_device_testing_net_next_step_btn.apply {
            this.visibility = View.VISIBLE
            this.isEnabled = true
            this.setTextColor(ContextCompat.getColor(context!!, R.color.base_white))
        }
    }

    /**
     * 创建一个指定大小的文件（单位：MB）
     */
    private fun createMbFile(size: Int) {
        val batchSize = 1024 * 1024
        val file = File(uploadFilePath)
        var fileOutputStream: FileOutputStream? = null
        try {
            if (file.exists()) {
                file.delete()
            }
            file.createNewFile()
            fileOutputStream = FileOutputStream(file)
            val fileChannel = fileOutputStream.channel
            for (i in 0 until size) {
                val buffer = ByteBuffer.allocate(batchSize)
                fileChannel.write(buffer)
            }
            fileOutputStream.close()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            fileOutputStream?.close()
            viewModel.uploadNetTest(uploadFilePath)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        viewModel.netState.removeObserver(netStateObserver)
        viewModel.uploadSpeed.removeObserver(netUploadSpeedObserver)
        viewModel.downloadSpeed.removeObserver(netDownloadSpeedObserver)
        viewModel.netIp.removeObserver(netIpObserver)
    }
}